#include "stackordercommand.h"
#include "document.h"

#include <QDebug>

namespace SymbolEditor
{

    StackOrderCommand::StackOrderCommand(UndoCommand *parent):
        UndoCommand(parent),
        m_itemId(-1),
        m_referenceItemId(-1),
        m_oldItemIndex(-1),
        m_oldRefIndex(-1)
    {
    }

    StackOrderCommand::~StackOrderCommand()
    {
    }

    void StackOrderCommand::setItem(quint64 id)
    {
        m_itemId = id;
    }

    void StackOrderCommand::setReferenceItem(quint64 id)
    {
        m_referenceItemId = id;
    }

    void StackOrderCommand::setStackOperation(StackOrderOperation operation)
    {
        m_operation = operation;
    }

    void StackOrderCommand::undo()
    {
        if (document()->itemStack().count() < 2)
        {
            // FIXME: log warning
            return;
        }

        switch (m_operation)
        {
            case StackToTop:
            case StackUp:
            {
                auto id = document()->itemStack().value(m_oldItemIndex);
                stackDown(id);
                break;
            }
            case StackToBottom:
            case StackDown:
            {
                stackUp(m_oldRefIndex, m_oldItemIndex);
                break;
            }
        }
    }

    void StackOrderCommand::stackDown(quint64 referenceId)
    {
        document()->stackItemBefore(m_itemId, referenceId);
    }

    void StackOrderCommand::redo()
    {
        if (document()->itemStack().count() < 2)
        {
            // FIXME: log warning
            setText("StackOrderCommand: stack has only one item!?!");
            return;
        }
        static const QString directions[] = {
            QString("to top"),
            QString("up"),
            QString("down"),
            QString("to bottom")
        };
        setText(QString("Move %1 item%2 %3").arg(1).arg("").arg(directions[m_operation]));

        m_oldItemIndex = document()->itemStack().indexOf(m_itemId);
        m_oldRefIndex = document()->itemStack().indexOf(m_referenceItemId);

        switch (m_operation)
        {
            case StackToTop:
            case StackUp:
            {
                stackUp(m_oldItemIndex, m_oldRefIndex);
                break;
            }
            case StackToBottom:
            case StackDown:
            {
                stackDown(m_referenceItemId);
                break;
            }
        }
    }

    void StackOrderCommand::stackUp(int itemIndex, int refIndex)
    {
        auto lastId = document()->itemStack().value(refIndex);
        do
        {
            auto id = document()->itemStack().value(itemIndex);
            document()->stackItemBefore(lastId, id);
            lastId = document()->itemStack().value(refIndex);
        }
        while (lastId != m_itemId);
    }

}
